package prac5;
import junit.framework.TestCase;

/**
 * JUnit testing for prac 5
 * 
 * @since          July, 2009
 * @version        2.0
 * @author         Brendon Taylor
 * @modified       Brendon Taylor (Feb 2010) - JavaDoc
 * @modified       Brendon Taylor (March 2010) - JavaDoc / Complexities / Post conditions
 * @modified       Brendon Taylor (August 2011) - Lowered required JUnit version to 3 and fixed assertEquals issue
 * @modified       Leo Li & Ian Moriarty (August 2011) - Expanded to meet the requirements of Prac 5
 * @input          none
 * @output         none
 * @errorHandling  {@link #testGladiatorialCombat()}: Exception caught if thrown from {@link Prac5#gladiatorialCombat(LinkedFighterStack, LinkedFighterStack)}
 * @knownBugs      none
 */
public class Prac5Test extends TestCase {
	/** Test armies: weakest to strongest */
	public static final int frequencyArmy[][] = 
		{{0, 0, 0},   // empty
		{0, 10, 0},  // 0S,  10A, 0C
		{3, 7,  0},  // 3S,  7A,  0C
		{10, 0, 0},  // 10S, 0A,  0C
		{7, 0, 3},   // 7S,  0A,  3C
		{0, 0, 10}}; // 0S,  0A,  10C

	/** Number of test cases to run */
//	public static final int TEST_CASES = 10;
//	public static final int TEST_CASES = 100;
//	public static final int TEST_CASES = 1000;
	public static final int TEST_CASES = 10000;

	/** Contains our armies to perform the tests */
	private LinkedFighterStack[] army;

	/**
	 * Adds units to a particular army.
	 * 
	 * @param       armyNo index of army
	 * @param       units String representation of army
	 * @pre         0 <= armyNo < ARMIES
	 * @post        army[armyNo] contains the correct number of fighter units
	 * @complexity  best and worst case O(C + A + S) ~= O(N)
	 *              where C is the number of cavalry units, 
	 *                    A is the number of archer units and 
	 *                    S is the number of soldier units
	 */
	private void addUnits(int armyNo, int[] frequencyUnits) {
//		      System.out.print("[" + armyNo + "] ");  
//		      for(int i = 0; i < frequencyUnits.length; i++)
//		              System.out.print(frequencyUnits[i] + " ");
//		      System.out.println();

		// Add the cavalry              
		for (int unit = 0; unit < frequencyUnits[2]; unit++) {
			army[armyNo].push(new Cavalry());
		}

		// Add the archers
		for (int unit = 0; unit < frequencyUnits[1]; unit++) {
			army[armyNo].push(new Archer());
		}

		// Add the soldiers
		for (int unit = 0; unit < frequencyUnits[0]; unit++) {
			army[armyNo].push(new Soldier());
		}               
	}

	/**
	 * Setup our test cases.
	 * 
	 * @post        army is initialised and contains our test armies
	 * @complexity  best and worst case O(N) where N is number of armies
	 */
	public void setUp() {
		army = new LinkedFighterStack[frequencyArmy.length];
		for (int i = 0; i < army.length; i++) {
			army[i] = new LinkedFighterStack();
			addUnits(i, frequencyArmy[i]);
		}
	}

	/**
	 * Test case: {@link Prac5#gladiatorialCombat(LinkedFighterStack, LinkedFighterStack)}.
	 * 
	 * @post        all test cases pass
	 * @complexity  best case and worse case: O(N) * O(GC)
	 *              where N is the number of test cases and 
	 *                    GC represents the complexity of {@link Prac5#gladiatorialCombat(LinkedFighterStack, LinkedFighterStack)}
	 */
	public void testGladiatorialCombat() {
//		for (int testCase = 0; testCase < TEST_CASES; testCase++) {
//			try {                   
//				int army1 = (int)(Math.random() * frequencyArmy.length);
//				int army2 = (int)(Math.random() * frequencyArmy.length);
//				int result = Prac5.gladiatorialCombat(army[army1].clone(), army[army2].clone());
//
//				System.out.println(army1  + " VS " + army2 + " winner is " + result);
//				if (army1 == army2)
//					assertEquals(0, result);
//				else if (army1 > army2)
//					assertEquals(1, result);
//				else
//					assertEquals(2, result);
//			}
//			catch(Exception e) {
//				System.out.println("testValidArmy: " + e);
//			}                               
//		}
		
		for (int i=0; i<frequencyArmy.length; i++){
			for(int j=i+1;j<frequencyArmy.length; j++){
				try {
					int army1 = i;
					int army2 = j;
					int result = Prac5.gladiatorialCombat(army[army1].clone(), army[army2].clone());

					System.out.println(army1  + " VS " + army2 + " winner is " + result);
					if (army1 == army2)
						assertEquals(0, result);
					else if (army1 > army2)
						assertEquals(1, result);
					else
						assertEquals(2, result);
				}
				catch(Exception e) {
					System.out.println("testValidArmy: " + e);
				}
			}                               
		}
	}
}
